package com.jfirer.validator.util;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.ElementDescriptor.ConstraintFinder;
import javax.validation.metadata.Scope;

public class ConstraintFinderImpl implements ConstraintFinder
{
    private Set<ConstraintDescriptor<?>> set;
    
    public ConstraintFinderImpl(Set<ConstraintDescriptor<?>> set)
    {
        this.set = set;
    }
    
    @Override
    public ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups)
    {
        Set<ConstraintDescriptor<?>> result = new HashSet<ConstraintDescriptor<?>>();
        for (Class<?> group : groups)
        {
            for (ConstraintDescriptor<?> descriptor : set)
            {
                if (descriptor.getGroups().contains(group))
                {
                    set.add(descriptor);
                }
            }
        }
        return new ConstraintFinderImpl(Collections.unmodifiableSet(result));
    }
    
    @Override
    public ConstraintFinder lookingAt(Scope scope)
    {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public ConstraintFinder declaredOn(ElementType... types)
    {
        Set<ConstraintDescriptor<?>> result = new HashSet<ConstraintDescriptor<?>>();
        for (ConstraintDescriptor<?> descriptor : set)
        {
            if (descriptor.getAnnotation().annotationType().isAnnotationPresent(Target.class))
            {
                Target target = descriptor.getAnnotation().annotationType().getAnnotation(Target.class);
                match: //
                for (ElementType targetType : target.value())
                {
                    for (ElementType elementType : types)
                    {
                        if (elementType == targetType)
                        {
                            result.add(descriptor);
                            break match;
                        }
                    }
                }
            }
            else
            {
                set.add(descriptor);
            }
        }
        return new ConstraintFinderImpl(Collections.unmodifiableSet(result));
    }
    
    @Override
    public Set<ConstraintDescriptor<?>> getConstraintDescriptors()
    {
        return set;
    }
    
    @Override
    public boolean hasConstraints()
    {
        return set.isEmpty() == false;
    }
    
}
